package net.atomarrow.services;

import java.lang.reflect.Method;
import java.util.List;

import net.atomarrow.annotation.Inject;
import net.atomarrow.aop.InterceptorKeeper;
import net.atomarrow.aop.ServiceInterceptor;
import net.atomarrow.ioc.ActionContext;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ServiceProxy implements MethodInterceptor {
	@Inject
	private InterceptorKeeper interceptorKeeper;
	private final Enhancer enhancer = new Enhancer();
	private List<ServiceInterceptor> interceptors;

	public Object getProxy(Object obj) {
		interceptors=interceptorKeeper.getServiceInterceptors();
		enhancer.setSuperclass(obj.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
	}

	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy)  {
		for(ServiceInterceptor interceptor:interceptors){
			interceptor.beforeAction(obj, method, args);
		}
		Object result = null;
		Throwable error=null;
		try{
		    result = proxy.invokeSuper(obj, args);
		} catch (Throwable e) {
			error=e;
			e.printStackTrace();
			ActionContext.getContext().setServiceException(e);
		}finally{
		    for(ServiceInterceptor interceptor:interceptors){
		        interceptor.afterAction(obj, method, args,result,error);
		    }
		}
		return result;
	}
}
